Send email with emayili



Send email with emayili

(or the gmailr R package)



Sharon Machlis at RLadies Johannesburg September 2022

Lesser known but great choice for email with R: emayili

  • Should work for almost any email account where you have SMTP access
  • Create email from an Rmd file including results of R code!
  • Name comes from the Zulu word for email, imeyili

4 easy steps

  • Create message object with envelope()
  • Add to, from, subject, body to the message
  • Create server connection object with server()
  • Send message using your server connection

Message syntax 1

Text

my_text_message <- envelope() |>
  from("me@gmail.com") |>
  to("you@email.com") |>
  subject("My Subject") |>
  text("Hello, world!")

HTML

my_html_message <- envelope() |>
  from("me@gmail.com") |>
  to("you@email.com") |>
  subject("My Subject") |>
  html("<p>Hello, world!</p>")

Message syntax 2

Text

my_message <- envelope(
  from = "me@gmail.com",
  to = "you@email.com",
  subject = "My Subject",
  text = "Hello, world!"
)

HTML

my_message <- envelope(
  from = "me@gmail.com",
  to = "you@email.com",
  subject = "My Subject",
  html = "<p>Hello, world!</p>"
)

Use render() for an .Rmd file with R code results

my_rmd_message <- envelope() |>
  from("me@gmail.com") |>
  to("you@email.com") |>
  subject("Email from an R Markdown file") |>
  render("my_email_rmd_file.Rmd")

Optional add attachment

my_rmd_message |>
  attachment("myfilename")

Make an RStudio code snippet!

usethis::edit_rstudio_snippets()

snippet my_email
  # library(emayili)
    my_rmd_message <- envelope() |>
      from("me@gmail.com") |>
      to("${1:to_address}") |>
      subject("${2:Subject}") |>
      render("${3:my_email_rmd_file}.Rmd") |>
      attachment("${4:myfilename}")

Connection setup syntax for most accounts

my_server_connection <- server(
  host = "smtp.thedomain.com",
  port = 465,
  username = "me@thedomain.com",
  password = "mypassword"
)

Connection setup syntax for most accounts

my_server_connection <- server(
  host = "smtp.thedomain.com",
  port = 465,
  username = "me@thedomain.com",
  password = "mypassword"
)

{fig-align=“center”, fig-alt=“red circle with line through it”}

Connection setup: Better

my_server_connection <- gmail(
  host = "smtp.thedomain.com",
  port = 465,
  username = "me@thedomain.com",
  password = Sys.getenv("MY_EMAIL_PASSWORD")
)

Edit your .Renviron file by adding MY_EMAIL_PASSWORD = "thePassWd" with usethis::edit_r_environ()

Best: Safeguard a password if script not scheduled/running unattended

library(keyring)
keyring_create("MySecurePasswords") # optional

key_set("MY_EMAIL_APP_PASSWORD", keyring = "MySecurePasswords") #specify keyring if not default

key_get("MY_EMAIL_APP_PASSWORD", keyring = "MySecurePasswords") # specify keyring if not default

keyring_lock("MySecurePasswords")

{fig.alt = “password prompt”}

Connection setup: Best

# key_set("MY_EMAIL_PASSWORD", keyring = "MySecurePasswords")
my_server_connection <- server(
  host = "smtp.thedomain.com",
  port = 465,
  username = "me@thedomain.com",
  password = key_get("MY_EMAIL_PASSWORD", keyring = "MySecurePasswords")
)

For Gmail only:

Set up 2-factor authentication and an app password

https://myaccount.google.com/security

2-step verification on and option for App passwords

Select app (Mail) and device (probably Mac or Windows Computer)

Choices to select app and select device

Connection to send from Gmail

my_gmail_server_connection <- gmail(
  username = "myusername",
  password = key_get("MY_GMAIL_APP_PASSWORD", keyring = "MySecurePasswords")
)

Create R Markdown doc for email with your R code results

Create email from that .Rmd file

library(emayili)
my_rmd_message <- envelope() |>
  from("me@machlis.com") |>
  to("someone@gmail.com") |>
  subject("Email from an R Markdown file") |>
  render("my_email_file.Rmd")

See metadata to be sent to server

print(my_rmd_message)
Date:                         Tue, 13 Sep 2022 01:13:25 GMT
X-Mailer:                     {emayili}-0.7.11
MIME-Version:                 1.0
From:                         me@machlis.com
To:                           someone@gmail.com
Subject:                      Email from an R Markdown file
# print(my_rmd_message, details = TRUE) to see everything sent, including css and encoding

Send!

my_server_connection(my_rmd_message)
# my_server_connection(my_rmd_message, verbose = TRUE) to see what's happening

Result in my Gmail

Gmail only: gmailr

Alternative specifically for Gmail

gmailr advantages

  • Create drafts before sending to view in Gmail
  • Read as well as send from Gmail

gmailr disadvantages

  • Gmail only
  • New authorization is complex

gmailr one-time setup

  • Set up your gmail account for API access
  • Download json authorization file
  • Install the gmailr package

Steps to send an email

  • Load gmailr
  • Load your authorization json file if it’s not in .Renviron
  • Create message text
  • Create message object including that text
  • Send message object

gmailr setup advice from package website

The easiest way to do this is via the Python Quickstart

Instructions for initial gmailr setup

https://developers.google.com/gmail/api/quickstart/python

Part of instructions with 'Create a project and enable the API' and 'Create credentials' links highlighted

Set up your gmail account for API access

Create a new project if you don’t already have one at

https://console.developer.google.com

Select New Project at upper right

Create your project

Choose a name for your project

Choose a name for your project screen

Set up your gmail account for API access

Click the ENABLE APIS AND SERVICES option

API & Services screen with Enable APIs option highlighted

Enable the Gmail API

Search for and select the Gmail API

Select Gmail API from the list after searching

Click Enable

Click the ENABLE button

Set up your gmail account for API access

https://developers.google.com/workspace/guides/create-credentials#desktop-app

Create credentials instructions

Create an OAuth client ID

Screen with OAuth client ID highlighted

Select Desktop app

{fig-align=“center”, fig-alt=“Screen with options for application type: Web app, Android, Chrome app, iOS, TVs, Desktop app, and UWP with Desktop app highlighted”}

Name OAuth client and download JSON file

Screen showing OAuth client created and option to download JSON

‘Publish’ your app

Image asking if app should be pushed to production

Store location of the JSON in your .Renvironment

usethis::edit_r_environ()

# In .Renvironment
GMAILR_APP = "path/to/google_oath_file.json"

Ready to email at last!

via giphy.com

Get text from my weather station for my email

library(rvest)
the_html <- read_html("https://apis.machlis.com/sharonwx")
the_text <- html_text2(the_html)
the_text <- gsub('"', '', the_text, fixed = TRUE)
cat(the_text)
The temperature at Sharon's weather station is 70.2°F (21.2°C) as of 09:10 PM ET on September 12. It feels like 71.5°F (21.9°C). The dew point is 69.3°F (20.7°C) with 97% humidity.

Syntax for plain email

my_email_message <- gm_mime() |>
  gm_to("some_email_address@somedomain.com") |>
  gm_from("myemail@gmail.com") |>
  gm_subject("My Subject") |>
  gm_text_body("My text")`

Syntax for HTML email

my_email_message <- gm_mime() |>
  gm_to("some_email_address@somedomain.com") |>
  gm_from("myemail@gmail.com") |>
  gm_subject("My Subject") |>
  gm_html_body("<p>My HTML text</p>")

My weather email

library(gmailr)
my_email_message <- gm_mime() |>
  gm_to("testing@machlis.com") |>
  gm_from("framinghamevents@gmail.com") |>
  gm_subject("Current Weather") |>
  gm_html_body(paste0("<p>", the_text, "</p>"))

Configure session to use stored json credentials

gm_auth_configure()

Test my email message

gm_create_draft(my_email_message)
image showing screen warning that google hasn't verified this app

Check drafts

Gmail showing a draft email with Current Weather

Send mail

gm_send_message(my_email_message)

Add attachment while creating message

my_email_message <- gm_mime() |>
  gm_to("testing@machlis.com") |>
  gm_from("framinghamevents@gmail.com") |>
  gm_subject("Current Weather") |>
  gm_html_body(paste0("<p>", the_text, "</p>")) |>
  gm_attach_file("asos_temps.csv")

Add attachment to existing message

my_email_message <- my_email_message |>
  gm_attach_file("asos_temps.csv")

Get monthly high temperatures for plot to add to email

library(vroom)
library(dplyr)
library(lubridate)
high_temps <- vroom("asos_temps.csv", show_col_types = FALSE) |>
  mutate(MonthStarting = floor_date(as.Date(valid), unit = "month")) |>
  group_by(MonthStarting) |>
  filter(tmpc == max(tmpc)) |>
  slice(1) |>
  ungroup() |>
  rename(HighTemp = tmpc)

glimpse(high_temps)
Rows: 20
Columns: 4
$ station       <chr> "FAHS", "FAHS", "FAHS", "FAHS", "FAHS", "FAHS", "FAHS", …
$ valid         <dttm> 2021-01-06 11:00:00, 2021-02-20 12:00:00, 2021-03-09 13…
$ HighTemp      <dbl> 37, 35, 38, 35, 33, 34, 34, 37, 38, 39, 41, 37, 35, 37, …
$ MonthStarting <date> 2021-01-01, 2021-02-01, 2021-03-01, 2021-04-01, 2021-05…

Create bar graph of monthly temperatures

library(ggplot2)
ggplot(high_temps, aes(x=MonthStarting, y=HighTemp)) + 
  geom_bar(stat="identity", color = "black", fill="#0072B2") +
  theme_classic() +
  xlab("Month") + ylab("") + ggtitle("Johannesburg Monthly High Temperatures", subtitle = "Data from https://mesonet.agron.iastate.edu/request/download.phtml?network=ZA__ASOS") +
    theme(plot.title = element_text(size = 24))
ggsave("images/monthly_high_temps.png", width = 6, height = 3, units = "in")

Syntax to add saved graph image to email body (in theory)

my_email_message <- gm_mime() |>
  gm_to("some_email_address@somedomain.com") |>
  gm_from("myemail@gmail.com") |>
  gm_subject("My Subject") |>
  gm_html_body('<p>My HTML text<br />
                <img src="cid:the_id_i_gave_my_image">   
               </p>') |>
  gm_attach_file("my_image_file.png", id = "the_id_i_gave_my_image")

Adding the plot and CSV to my email

my_email_message_w_image <- gm_mime() |>
  gm_to("testing@machlis.com") |>
  gm_from("framinghamevents@gmail.com") |>
  gm_subject("Temperatures in Johannesburg") |>
  gm_html_body(paste0('<p>Attached is a CSV with hourly temperature readings in Johannesburg. Below is a graph of monthly highs.</p><br /><img src="hightemps"><p>Data from https://mesonet.agron.iastate.edu/request/download.phtml?network=ZA__ASOS</p>')) |>
  gm_attach_file("asos_temps.csv") |>
  gm_attach_file("images/monthly_high_temps.png", id = "hightemps")

gm_send_message(my_email_message_w_image)

What I saw in my desktop email client

email with blue bar graph showing monthly high temperatures

What I saw in my Web mail

email with small image of graph surrounded by a lot of blue text

More email R package options

More Resources

This GitHub repo: https://www.github.com/smach/RLadiesJohannesburg

Keep your passwords and tokens secure with the keyring package

My InfoWorld article on gmailr

Do More With R: https://bit.ly/domorewithR

Find me on Twitter: @sharon000